package lipengfei.botaiframework.mybatisplus.extend.lazy;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.spring.SpringUtil;
import lipengfei.botaiframework.mybatisplus.extend.annotation.BeanValue;
 

/**
   *  懒加载工厂，结合@BeanValue注解，实现懒加载,提高系统效率。
 *  
 * */
public class LazyloadFactory implements MethodInterceptor {
	
	/**数据库实体类对象*/
	private Object target;
 
	public LazyloadFactory(Object target) {
		this.target = target;
	}
 
	@Override
	public Object intercept(Object obj, Method method, Object[] args,MethodProxy proxy) throws Throwable {
		
		String methodName = method.getName();
		if (methodName.startsWith("get")) {
			String fieldName =  StrUtil.removePreAndLowerFirst(methodName, 3);
			Field field= ReflectUtil.getField(target.getClass(), fieldName);
			if(field!=null) {
				BeanValue beanValue=field.getAnnotation(BeanValue.class);
				if(beanValue!=null) {
					/****获取注解的值****/
					Class<?> beanValueClass = beanValue.beanClass();
					String beanValueMethod = beanValue.method();
				    String beanValueParamFiled = beanValue.paramFiled();
				    String[]  paramFiledArr=beanValueParamFiled.split(",");
				    
				    List<Class<?>>  paramClassList= new ArrayList<Class<?>>();//方法参数的Class类型
				    List<Object>  paramValueList= new ArrayList<Object>();//方法参数的具体value
				   
				    
				    for(String paramFiledStr:paramFiledArr) {
				    	if(StrUtil.isNotBlank(paramFiledStr)) {
				    		if(paramFiledStr.contains("#")) {
				    			String paramName=paramFiledStr.replace("#", "").replace("{", "").replace("}", "");
				    			Field paramField = ReflectUtil.getField(target.getClass(), paramName);
				    			//Field paramField = fieldList.stream().filter(a->a.getName().equals(paramName)).collect(Collectors.toList()).get(0);
				    			if(method.equals("selectById")) {
				    				paramClassList.add(Serializable.class);
							    }else {
							    	paramClassList.add(paramField.getType());
							    }
				    			paramField.setAccessible(true);
				    			Object paramValue = paramField.get(target);
				    			paramValueList.add(paramValue);
				    		}else {
				    			paramClassList.add(String.class);
				    			paramValueList.add(paramFiledStr);
				    		}
				    	}
				    }
				    
				    
				    //集合转数据，否则无法获取方法。
				    Class<?>[] paramArr =new Class<?>[paramValueList.size()];
				    for(int i=0;i<paramClassList.size();i++) {
					  paramArr[i]=paramClassList.get(i);
				    }
				    field.setAccessible(true); 
				    
				    Object beanClassInvoke = SpringUtil.getBean(beanValueClass);
				    Method methodInvoke = ReflectUtil.getMethodByName(beanClassInvoke.getClass(), beanValueMethod);
					Object value = methodInvoke.invoke(beanClassInvoke,paramValueList.toArray());
					field.set(target, value); 
				}

			}

			
		}

		Object result = proxy.invoke(target, args);
		return result;
	}
	
}
 